package com.gd.iot.energy.util;

import com.gd.iot.energy.code.ResponseCode;
import com.gd.iot.energy.exception.MyException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.util.Assert;

import java.lang.reflect.Constructor;
import java.util.Collection;
import java.util.Iterator;


/**
 * @ClassName: CustomBeanUtils
 * @Description: pojo工具类
 */
@Slf4j
public class CustomBeanUtils extends BeanUtils {

	public static final String CONVERT_ERROR = "实体转换错误";

	/**
	 * 拷贝属性
	 * @param source 源对象
	 * @param target 目标对象
	 * @param <E> 源对象
	 * @param <T> 目标对象
	 * @return 目标对象
	 */
	public static <E, T> void convert(E source,T target){
		BeanUtils.copyProperties(source,target);
	}

	/**
	 * @Title: convertPojo
	 * @Description: pojo转换方法
	 * @param source 待转换集合
	 * @param type 待转类型
	 * @return
	 * @return: Collection<T>
	 */
	public static <E, T> Collection<T> convertPojo(Collection<E> source, Class<T> type) {

		try {
			Assert.notEmpty(source, "Source must not be empty");
			Assert.notNull(type, "Type must not be null");

			String sourceType = source.getClass().getName();
			@SuppressWarnings("unchecked")
			Class<? extends Collection<T>> clazz = (Class<? extends Collection<T>>) Class.forName(sourceType);
			Constructor<? extends Collection<T>> constructor = clazz.getConstructor(int.class);
			Collection<T> collection = constructor.newInstance(source.size());

			convertPojo(source, collection, type);

			return clazz.cast(collection);

		} catch (Exception e) {
			log.error(CONVERT_ERROR, e);
			throw new MyException(ResponseCode.SYSTEM_ERROR);
		}
	}

	/**
	 * @Title: convertPojo
	 * @Description: pojo转换方法
	 * @param source 待转换的集合
	 * @param target 转换后的集合
	 * @param type 要转换的类型
	 * @return: void
	 */
	public static <E, T> void convertPojo(Collection<E> source, Collection<T> target, Class<T> type) {

		try {
			if(source.isEmpty()){
				return;
			}
			Assert.notNull(target, "Target must not be null");
			Assert.notNull(type, "Type must not be null");

			Iterator<E> iterator = source.iterator();
			while (iterator.hasNext()) {
				E e = iterator.next();
				T t = type.newInstance();
				copyProperties(e, t);
				target.add(t);
			}
		} catch (Exception e) {
			log.error(CONVERT_ERROR, e);
			throw new MyException(ResponseCode.SYSTEM_ERROR);
		}
	}
}
